package com.bdmc.task.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.bdmc.common.annotation.DataColumn;
import com.bdmc.common.annotation.DataPermission;
import com.bdmc.common.core.page.TableDataInfo;
import com.bdmc.common.core.domain.PageQuery;
import com.bdmc.task.domain.TaskPlanDetail;
import com.bdmc.task.domain.bo.TaskPlanDetailBo;
import com.bdmc.task.service.ITaskPlanDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bdmc.common.core.mybatisplus.core.ServicePlusImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bdmc.common.utils.StringUtils;
import com.bdmc.task.domain.bo.TaskWorkPlanBo;
import com.bdmc.task.domain.vo.TaskWorkPlanVo;
import com.bdmc.task.domain.TaskWorkPlan;
import com.bdmc.task.mapper.TaskWorkPlanMapper;
import com.bdmc.task.service.ITaskWorkPlanService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 排班计划Service业务层处理
 *
 * @author bdmc
 * @date 2022-03-06
 */
@Service
public class TaskWorkPlanServiceImpl extends ServicePlusImpl<TaskWorkPlanMapper, TaskWorkPlan, TaskWorkPlanVo> implements ITaskWorkPlanService {

    @Autowired
    private ITaskPlanDetailService planDetailService;

    @Override
    public TaskWorkPlanVo queryById(Integer workPlanId){
        return getVoById(workPlanId);
    }

    @DataPermission({
            @DataColumn(value = "d.dept_id")
    })
    @Override
    public TableDataInfo<TaskWorkPlanVo> queryPageList(TaskWorkPlanBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TaskWorkPlan> lqw = buildQueryWrapper(bo);
        Page<TaskWorkPlanVo> result = pageVo(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<TaskWorkPlanVo> mySelectPage(TaskWorkPlanBo bo, PageQuery pageQuery) {
        return TableDataInfo.build(baseMapper.mySelectPage(pageQuery.build(),bo));
    }


    @Override
    public List<TaskWorkPlanVo> queryList(TaskWorkPlanBo bo) {
        return baseMapper.mySelectPage(bo);
    }

    private LambdaQueryWrapper<TaskWorkPlan> buildQueryWrapper(TaskWorkPlanBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TaskWorkPlan> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getWorkPlanName()), TaskWorkPlan::getWorkPlanName, bo.getWorkPlanName());
        lqw.eq(bo.getDeptId() != null, TaskWorkPlan::getDeptId, bo.getDeptId());
        lqw.eq(bo.getFenceId() != null, TaskWorkPlan::getFenceId, bo.getFenceId());
        lqw.eq(bo.getAlarmRuleId() != null, TaskWorkPlan::getAlarmRuleId, bo.getAlarmRuleId());
        lqw.eq(bo.getPersonId() != null, TaskWorkPlan::getPersonId, bo.getPersonId());
        lqw.eq(StringUtils.isNotBlank(bo.getPlanMonth()), TaskWorkPlan::getPlanMonth, bo.getPlanMonth());
        return lqw;
    }

    @Transactional
    @Override
    public Boolean insertByBo(TaskWorkPlanBo bo) {
        if(bo.getWorkPlanType().equals("car")){
            for (String carIdStr:bo.getCarIds().split(",")) {
                Long carId = Long.parseLong(carIdStr);
                Long count = checkObjectPlanExist(carId,bo.getPlanMonth(),bo.getWorkPlanType());
                if(count>0)
                    continue;
                TaskWorkPlanBo temp = bo.clone();
                temp.setCarId(carId);
                TaskWorkPlan addTemp = BeanUtil.toBean(temp, TaskWorkPlan.class);
                save(addTemp);
                temp.getPlanDetailList().forEach(r->r.setWorkPlanId(addTemp.getWorkPlanId()));
                planDetailService.saveBatch(BeanUtil.copyToList(temp.getPlanDetailList(), TaskPlanDetail.class));
            }
        }else{
            for (String personIdStr:bo.getPersonIds().split(",")) {
                Long personId = Long.parseLong(personIdStr);
                Long count = checkObjectPlanExist(personId,bo.getPlanMonth(),bo.getWorkPlanType());
                if(count>0)
                    continue;
                TaskWorkPlanBo temp = bo.clone();
                temp.setPersonId(personId);
                TaskWorkPlan addTemp = BeanUtil.toBean(temp, TaskWorkPlan.class);
                save(addTemp);
                temp.getPlanDetailList().forEach(r->r.setWorkPlanId(addTemp.getWorkPlanId()));
                planDetailService.saveBatch(BeanUtil.copyToList(temp.getPlanDetailList(), TaskPlanDetail.class));
            }
        }


        return true;
    }

    @Override
    public Boolean updateByBo(TaskWorkPlanBo bo) {
        TaskWorkPlan update = BeanUtil.toBean(bo, TaskWorkPlan.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TaskWorkPlan entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        boolean removeResult = removeByIds(ids);
        if(removeResult){
            LambdaQueryWrapper<TaskPlanDetail> w1 = new LambdaQueryWrapper<>();
            w1.in(TaskPlanDetail::getWorkPlanId,ids);
            planDetailService.remove(w1);
        }
        return removeResult;
    }

    /**
     * 检查是否已经添加过该月的用户排班
     *
     * @param objectId  人员或车辆id
     * @param planMonth 年月
     * @return count
     */
    @Override
    public Long checkObjectPlanExist(Long objectId, String planMonth,String workPlanType) {
        LambdaQueryWrapper<TaskWorkPlan> w1 = new LambdaQueryWrapper<>();
        if (workPlanType.equals("person")){
            w1.eq(TaskWorkPlan::getPersonId,objectId).eq(TaskWorkPlan::getPlanMonth,planMonth);
        }else if(workPlanType.equals("car")){
            w1.eq(TaskWorkPlan::getCarId,objectId).eq(TaskWorkPlan::getPlanMonth,planMonth);
        }

        return count(w1);
    }
}
